home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / splinux.c < prev    next >
C/C++ Source or Header  |  1995-02-26  |  13KB  |  551 lines

  1. /*
  2.  * Spider
  3.  *
  4.  * Copyright (C) Evan Harris, 1993, 1994, 1995.
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <vga.h>
  13. #include <vgamouse.h>
  14.  
  15. #include "vga16.h"
  16. #include "mouse.h"
  17. #include "key.h"
  18. #include "spider.h"
  19.  
  20.  
  21. #define SP_SCREENMODE G640x480x16
  22. #define SP_SCREENWIDTH 640
  23. #define SP_SCREENHEIGHT 480
  24.  
  25. #define SP_TEXTFG 1
  26. #define SP_TEXTBG 0
  27. #define SP_BUTTONFG 2
  28. #define SP_BUTTONBG 6
  29. #define SP_MOUSEFG 5
  30. #define SP_MOUSEDARKFG 2
  31. #define SP_OUTLINE 6
  32.  
  33. #define NUMCARDIMAGES 52
  34. #define CARDACTUALWIDTH 53
  35. #define CARDIMAGEWIDTH 56
  36. #define CARDIMAGEHEIGHT 80
  37.  
  38. #define VERSION "SPIDER\n v1.3"
  39.  
  40. #ifndef CARDSFILE
  41. #define CARDSFILE "Cards56x80"
  42. #endif
  43. #ifndef CARDSMOUSESAMPLERATE
  44. #define CARDSMOUSESAMPLERATE MOUSE_DEFAULTSAMPLERATE
  45. #endif
  46.  
  47. #define USLEEP_TIME 30000
  48.  
  49.  
  50. #define CARDTOIMAGE(card)    (card % NUMCARDIMAGES)
  51.  
  52. #define BITWIDTH CARDIMAGEWIDTH /* multiple of 8 */
  53. #define BITHEIGHT CARDIMAGEHEIGHT
  54. #define BITSHOWLEFT 24        /* multiple of 8 */
  55. #define BITTOP 24
  56. #define COLWIDTH BITWIDTH
  57. #define TOPROWHEIGHT    (BITHEIGHT + 4)
  58.  
  59.  
  60. #define SP_QUITLEFT (SP_SCREENWIDTH - 80)
  61. #define SP_QUITRIGHT (SP_QUITLEFT + 80)
  62. #define SP_QUITBOTTOM 132
  63. #define SP_QUITTOP (SP_QUITBOTTOM - 16)
  64.  
  65. #define SP_NEWGAMELEFT SP_QUITLEFT
  66. #define SP_NEWGAMERIGHT SP_QUITRIGHT
  67. #define SP_NEWGAMEBOTTOM 48
  68. #define SP_NEWGAMETOP (SP_NEWGAMEBOTTOM - 16)
  69.  
  70. #define SP_RESTARTLEFT SP_QUITLEFT
  71. #define SP_RESTARTRIGHT SP_QUITRIGHT
  72. #define SP_RESTARTBOTTOM 76
  73. #define SP_RESTARTTOP (SP_RESTARTBOTTOM - 16)
  74.  
  75. #define SP_UNDOLEFT SP_QUITLEFT
  76. #define SP_UNDORIGHT SP_QUITRIGHT
  77. #define SP_UNDOBOTTOM 104
  78. #define SP_UNDOTOP (SP_UNDOBOTTOM - 16)
  79.  
  80.  
  81. #define STOCKLEFT 0
  82. #define STOCKTOP 0
  83. #define FOUNDLEFT (2 * BITWIDTH)
  84. #define FOUNDTOP 0
  85.  
  86.  
  87. #define SP_PALETTESIZE 7
  88.  
  89. int palette[SP_PALETTESIZE * 3] = {
  90.     0x00, 0x20, 0x00,        /* green */
  91.     0x3f, 0x3f, 0x3f,        /* white */
  92.     0x00, 0x00, 0x00,        /* black */
  93.     0x37, 0x00, 0x00,        /* red */
  94.     0x00, 0x00, 0x20,        /* blue */
  95.     0x3f, 0x3f, 0x00,        /* yellow */
  96.     0x1a, 0x1a, 0x1a,        /* grey */
  97. };
  98.  
  99. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  100. static void LoadCards(char *file);
  101. static long GetMouseButton(void);
  102. static long WhileMouseButton(void);
  103. static int ParsePos(long pos, int downcard, int buttonup);
  104.  
  105. static unsigned char ***imageCard;
  106. static unsigned char **backCard;
  107. static unsigned char **outlineCard;
  108. static unsigned char *blankLine;
  109.  
  110.  
  111. void
  112. InitDisplay(int argc, char **argv)
  113. {
  114.     vga_disabledriverreport();
  115.     vga_init();
  116. #if !defined(CARDSMOUSE)
  117.     vga_setmousesupport(1);
  118. #endif
  119.     
  120.     if (vga_setmode(SP_SCREENMODE) != 0) {
  121.     fprintf(stderr, "Mode %s not available!\n",
  122.         vga_getmodename(SP_SCREENMODE));
  123.     exit(1);
  124.     }
  125.  
  126. #if defined(CARDSMOUSE)
  127.     mouse_init("/dev/mouse", vga_getmousetype(), CARDSMOUSESAMPLERATE);
  128.     mouse_setxrange(0, SP_SCREENWIDTH - 1);
  129.     mouse_setyrange(0, SP_SCREENHEIGHT - 1);
  130.     mouse_setwrap(MOUSE_NOWRAP);
  131. #endif
  132.  
  133.     vga16_init();
  134.  
  135.     LoadCards(CARDSFILE);
  136.  
  137.     blankLine = (unsigned char *)calloc(SP_SCREENWIDTH, sizeof(unsigned char));
  138.     if (blankLine == NULL) {
  139.     fprintf(stderr, "Error: cannot get memory for blankLine\n");
  140.     exit(1);
  141.     }
  142.  
  143.     vga_setpalvec(0, SP_PALETTESIZE, &palette[0]);
  144.  
  145.     vga16_text(SP_NEWGAMELEFT, SP_NEWGAMEBOTTOM, " NEW GAME ",
  146.            SP_BUTTONFG, SP_BUTTONBG);
  147.     vga16_text(SP_RESTARTLEFT, SP_RESTARTBOTTOM, " RESTART  ",
  148.            SP_BUTTONFG, SP_BUTTONBG);
  149.     vga16_text(SP_UNDOLEFT, SP_UNDOBOTTOM, "   UNDO   ",
  150.            SP_BUTTONFG, SP_BUTTONBG);
  151.     vga16_text(SP_QUITLEFT, SP_QUITBOTTOM, "   QUIT   ",
  152.            SP_BUTTONFG, SP_BUTTONBG);
  153.  
  154.     vga16_text(SP_SCREENWIDTH - 64, 200, VERSION, SP_TEXTFG, SP_TEXTBG);
  155. }
  156.  
  157.  
  158. static void
  159. LoadCards(char *file)
  160. {
  161.     int i, j, k, l, c, colour;
  162.     FILE *f;
  163.  
  164.     f = fopen(file, "r");
  165.     if (f == NULL) {
  166.     fprintf(stderr, "Cannot find '%s'\n", file);
  167.     exit(1);
  168.     }
  169.  
  170.     imageCard = (unsigned char ***)malloc(NUMCARDIMAGES
  171.                       * sizeof(unsigned char **));
  172.     if (imageCard == NULL) {
  173.     fprintf(stderr, "Error: cannot get memory for imageCard\n");
  174.     exit(1);
  175.     }
  176.     for (i = 0; i < NUMCARDIMAGES; i++) {
  177.     imageCard[i] = (unsigned char **)malloc(CARDIMAGEHEIGHT
  178.                         * sizeof(unsigned char *));
  179.     if (imageCard == NULL) {
  180.         fprintf(stderr, "Error: cannot get memory for imageCard[%d]\n",
  181.             i);
  182.         exit(1);
  183.     }
  184.     for (j = 0; j < CARDIMAGEHEIGHT; j++) {
  185.         imageCard[i][j] = (unsigned char *)malloc(CARDIMAGEWIDTH
  186.                               * sizeof(unsigned char));
  187.         if (imageCard[i][j] == NULL) { 
  188.         fprintf(stderr,
  189.             "Error: cannot get memory for imageCard[%d][%d]\n",
  190.             i, j);
  191.         exit(1);
  192.         }
  193.         
  194.         if (SUIT(i) == SPADES || SUIT(i) == CLUBS) {
  195.         colour = 2;
  196.         } else {
  197.         colour = 3;
  198.         }
  199.         if (TYPE(i) < JACK) {
  200.         for (k = 0; k < CARDIMAGEWIDTH / 8; k++) {
  201.             if ((c = getc(f)) == EOF) {
  202.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  203.             exit(1);
  204.             }
  205.             for (l = 0; l < 8; l++) {
  206.             imageCard[i][j][8 * k + l] =
  207.                 (c & 1 << (7 - l)) ? colour : 1;
  208.             }
  209.         }
  210.         for (k = CARDACTUALWIDTH; k < CARDIMAGEWIDTH; k++) {
  211.             imageCard[i][j][k] = 0;
  212.         }
  213.         } else {
  214.         for (k = 0; k < CARDIMAGEWIDTH / 2; k++) {
  215.             if ((c = getc(f)) == EOF) {
  216.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  217.             exit(1);
  218.             }
  219.             imageCard[i][j][2 * k] = (unsigned char)c >> 4;
  220.             imageCard[i][j][2 * k + 1] = (unsigned char)c & 0xf;
  221.         }
  222.         }
  223.     }
  224.     }
  225.  
  226.     fclose(f);
  227.  
  228.     backCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
  229.     outlineCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
  230.     if (backCard == NULL || outlineCard == NULL) {
  231.     fprintf(stderr, "Error: cannot get memory for cards");
  232.     exit(1);
  233.     }
  234.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  235.     backCard[i] = malloc(CARDIMAGEWIDTH * sizeof(unsigned char));
  236.     outlineCard[i] = calloc(CARDIMAGEWIDTH, sizeof(unsigned char));
  237.     if (backCard[i] == NULL || outlineCard[i] == NULL) {
  238.         fprintf(stderr, "Error: cannot get memory for cards");
  239.         exit(1);
  240.     }
  241.     }
  242.     for (i = 0; i < CARDACTUALWIDTH; i++) {
  243.     outlineCard[0][i] = SP_OUTLINE;
  244.     outlineCard[CARDIMAGEHEIGHT - 1][i] = SP_OUTLINE;
  245.     }
  246.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  247.     outlineCard[i][0] = SP_OUTLINE;
  248.     outlineCard[i][CARDACTUALWIDTH - 1] = SP_OUTLINE;
  249.     }
  250.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  251.     for (j = 0; j < CARDACTUALWIDTH; j++) {
  252.         if ((i / 4) % 2 == (j / 4) % 2) {
  253.         backCard[i][j] = 4;
  254.         } else {
  255.         backCard[i][j] = 1;
  256.         }
  257.     }
  258.     for (; j < CARDIMAGEWIDTH; j++) {
  259.         backCard[i][j] = 0;
  260.     }
  261.     }
  262. }
  263.  
  264.  
  265. static unsigned char columnTop[COLUMNS];
  266.  
  267. /* We redisplay a whole column, rather than do anything tricky. */
  268. void
  269. DisplayColumn(short col)
  270. {
  271.     unsigned char **image;
  272.     int card, length, row, height, line;
  273.     int bittop = BITTOP;
  274.     
  275.     if (col == STOCK || col == PILE) {
  276.     DisplayStockPile();
  277.     return;
  278.     }
  279.  
  280.     for (card = column[col], length = 0; card != NOCARD; card = next[card])
  281.     length++;
  282.  
  283.     if (length > 0 && (SP_SCREENHEIGHT - TOPROWHEIGHT) / length < bittop)
  284.     bittop = (SP_SCREENHEIGHT - TOPROWHEIGHT) / length;
  285.     columnTop[col] = bittop;
  286.  
  287.     card = column[col];
  288.     row = TOPROWHEIGHT;
  289.     col = col * COLWIDTH;
  290.  
  291.     while (card != NOCARD && row < SP_SCREENHEIGHT - 1) {
  292.     if (hidden[card])
  293.         image = backCard;
  294.     else
  295.         image = imageCard[CARDTOIMAGE(card)];
  296.     if (next[card] == NOCARD)
  297.         height = BITHEIGHT;
  298.     else
  299.         height = bittop;
  300.     if (row + height >= SP_SCREENHEIGHT)
  301.         height -= row + height - SP_SCREENHEIGHT + 1;
  302.  
  303.     for (line = 0; line < height; line++) {
  304.         vga16_drawscansegment(image[line], col, row + line, BITWIDTH);
  305.     }
  306.  
  307.     row += height;
  308.     card = next[card];
  309.     }
  310.     for (; row < SP_SCREENHEIGHT; row++) {
  311.     vga16_drawscansegment(blankLine, col, row, BITWIDTH);
  312.     }
  313.  
  314.     return;
  315. }
  316.  
  317.  
  318. void
  319. DisplayStockPile()
  320. {
  321.     unsigned char **card;
  322.     int line;
  323.     
  324.     if (stock == NOCARD) {
  325.     card = outlineCard;
  326.     } else {
  327.     card = backCard;
  328.     }
  329.     for (line = 0; line < CARDIMAGEHEIGHT; line++) {
  330.     vga16_drawscansegment(card[line], STOCKLEFT, STOCKTOP + line,
  331.                   BITWIDTH);
  332.     }
  333. }
  334.  
  335.  
  336. void
  337. DisplayFoundations()
  338. {
  339.     unsigned char **card;
  340.     int i, line, foundleft;
  341.  
  342.     foundleft = FOUNDLEFT;
  343.     for (i = 0; i < NUMSUITS; i++) {
  344.     if (foundation[i] == 0) {
  345.         card = outlineCard;
  346.     } else {
  347.         card = imageCard[CARD(i % 4, ACE)];
  348.     }
  349.     for (line = 0; line < CARDIMAGEHEIGHT; line++) {
  350.         vga16_drawscansegment(card[line], foundleft, FOUNDTOP + line,
  351.                   BITWIDTH);
  352.     }
  353.     foundleft += BITWIDTH;
  354.     }
  355. }
  356.  
  357.  
  358. short
  359. GetCmd()
  360. {
  361.     int c, c1;
  362.     
  363.     for (c = NOCARD; c == NOCARD;) {
  364.     c = GetMouseButton();
  365.     c1 = WhileMouseButton();
  366.     if (c >= 0) {
  367.         c = ParsePos(c, -1, 0);
  368.         c1 = ParsePos(c1, c, 1);
  369.  
  370.         if (c == c1 && (c >= 0 || c == FROMSTOCK)) {
  371.         return c;
  372.         }
  373.         if (c >= 0 && c1 == TOFOUNDATION) {
  374.         return TOHINT(FOUNDATION) | c;
  375.         }
  376.         if (c >= 0 && ISCOLSPEC(c1)) {
  377.         return TOHINT(SPECTOCOL(c1)) | c;
  378.         }
  379.         
  380.         c = NOCARD;
  381.     }
  382.     }
  383.  
  384.     return c;
  385. }
  386.  
  387.  
  388. static int oldx = -1, oldy, oldcolour[40];
  389.  
  390. static long
  391. GetMouseButton()
  392. {
  393.     int x, y, button, key;
  394.  
  395.     x = mouse_getx();
  396.     y = mouse_gety();
  397.     if (x != oldx || y != oldy) {
  398.     if (oldx != -1) {
  399.         RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  400.     }
  401.     SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  402.     RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
  403.     oldx = x;
  404.     oldy = y;
  405.     }
  406.     
  407.     for (;;) {
  408.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  409.  
  410.     if (mouse_update()) {
  411.         x = mouse_getx();
  412.         y = mouse_gety();
  413.         button = mouse_getbutton();
  414.  
  415.         if (x != oldx || y != oldy) {
  416.         if (oldx != -1) {
  417.             RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  418.         }
  419.         SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  420.         RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
  421.         oldx = x;
  422.         oldy = y;
  423.         }
  424.     
  425.         if (button & MOUSE_LEFTBUTTON) {
  426.         break;
  427.         }
  428.     }
  429.     if ((key = key_getkey()) != -1) {
  430.         switch (key) {
  431.           case 'n':
  432.           case 'N':
  433.         return NEWGAME;
  434.           case 'r':
  435.           case 'R':
  436.         return RESTART;
  437.           case 'u':
  438.           case 'U':
  439.         return UNDO;
  440.           case 'q':
  441.           case 'Q':
  442.         return QUIT;
  443.           case '\014':
  444.         vga16_redrawscreen();
  445.         break;
  446.           default:
  447.         break;
  448.         }
  449.     }
  450.     }
  451.  
  452.     if (x >= SP_NEWGAMELEFT && x < SP_NEWGAMERIGHT
  453.     && y > SP_NEWGAMETOP && y <= SP_NEWGAMEBOTTOM) {
  454.     return NEWGAME;
  455.     }
  456.     if (x >= SP_RESTARTLEFT && x < SP_RESTARTRIGHT
  457.     && y > SP_RESTARTTOP && y <= SP_RESTARTBOTTOM) {
  458.     return RESTART;
  459.     }
  460.     if (x >= SP_UNDOLEFT && x < SP_UNDORIGHT
  461.     && y > SP_UNDOTOP && y <= SP_UNDOBOTTOM) {
  462.     return UNDO;
  463.     }
  464.     if (x >= SP_QUITLEFT && x < SP_QUITRIGHT
  465.     && y > SP_QUITTOP && y <= SP_QUITBOTTOM) {
  466.     return QUIT;
  467.     }
  468.  
  469.     return (x << 9) | y;
  470. }
  471.  
  472.  
  473. static long
  474. WhileMouseButton()
  475. {
  476.     int x, y, button;
  477.  
  478.     for (;;) {
  479.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  480.  
  481.     mouse_update();
  482.     x = mouse_getx();
  483.     y = mouse_gety();
  484.     button = mouse_getbutton();
  485.  
  486.     if (x != oldx || y != oldy) {
  487.         if (oldx != -1) {
  488.         RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  489.         }
  490.         SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  491.         RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
  492.         oldx = x;
  493.         oldy = y;
  494.     }
  495.     
  496.     if (!(button & MOUSE_LEFTBUTTON)) {
  497.         break;
  498.     }
  499.     }
  500.  
  501.     if (oldx != -1) {
  502.     RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
  503.     }
  504.     oldx = -1;
  505.  
  506.     return (x << 9) | y;
  507. }
  508.  
  509.  
  510. static int
  511. ParsePos(long pos, int downcard, int buttonup)
  512. {
  513.     int x, y, card, row, bittop;
  514.     
  515.     x = pos >> 9;
  516.     y = pos & 0x1ff;
  517.     if (x >= STOCKLEFT && x < STOCKLEFT + BITWIDTH
  518.     && y >= STOCKTOP && y < STOCKTOP + CARDIMAGEHEIGHT) {
  519.     return FROMSTOCK;
  520.     }
  521.     if (buttonup
  522.     && x >= FOUNDLEFT && x < FOUNDLEFT + NUMSUITS * COLWIDTH
  523.     && y >= FOUNDTOP && y < FOUNDTOP + CARDIMAGEHEIGHT) {
  524.     return TOFOUNDATION;
  525.     }
  526.  
  527.     if (x / COLWIDTH > 9 || y < TOPROWHEIGHT) {
  528.     return NOCARD;
  529.     }
  530.  
  531.     card = column[x / COLWIDTH];
  532.     bittop = columnTop[x / COLWIDTH];
  533.     row = TOPROWHEIGHT;
  534.  
  535.     while (card != NOCARD) {
  536.     if ((next[card] != NOCARD && y >= row && y < row + bittop)
  537.         || (next[card] == NOCARD && y >= row && y < row + BITHEIGHT)) {
  538.         if (!hidden[card] && (downcard == -1 || downcard == card)) {
  539.         return card;
  540.         }
  541.     }
  542.     card = next[card];
  543.     row += bittop;
  544.     }
  545.     if (buttonup) {
  546.     return COLTOSPEC(x / COLWIDTH);
  547.     }
  548.  
  549.     return NOCARD;
  550. }
  551.